home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / program / ny_src.zip / IBBSNY.CPP < prev    next >
C/C++ Source or Header  |  1997-04-22  |  48KB  |  1,837 lines

  1. //#include <assert.h>
  2. #include <ctype.h>
  3. #include <string.h>
  4. #include <dir.h>
  5. #include <time.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <io.h>
  9. #include <dos.h>
  10. #include <fcntl.h>
  11. #include <sys\stat.h>
  12.  
  13. //typedef unsigned int WORD;
  14. //typedef unsigned long DWORD;
  15.  
  16. #include "ny2008.h"
  17. //#include "ibbsny.h"
  18. extern unsigned _stklen;
  19. int ibbsi=FALSE;
  20. int ibbsi_operator=FALSE;
  21. int ibbsi_game_num=0;
  22. char bbs_namei[37];
  23.  
  24.  
  25. char aszShortMonthName[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
  26.                  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  27.  
  28. /*tBool DirExists(const char *pszDirName)
  29.    {
  30.    char szDirFileName[PATH_CHARS + 1];
  31.    struct ffblk DirEntry;
  32.  
  33. //   if(pszDirName==NULL) return(FALSE);
  34. //   if(strlen(pszDirName)>PATH_CHARS) return(FALSE);
  35.    assert(pszDirName != NULL);
  36.    assert(strlen(pszDirName) <= PATH_CHARS);
  37.  
  38.    strcpy(szDirFileName, pszDirName);
  39.  
  40.    /* Remove any trailing backslash from directory name -/
  41.    if(szDirFileName[strlen(szDirFileName) - 1] == '\\')
  42.       {
  43.       szDirFileName[strlen(szDirFileName) - 1] = '\0';
  44.       }
  45.  
  46.    /* Return true iff file exists and it is a directory -/
  47.    return(findfirst(szDirFileName, &DirEntry, FA_ARCH|FA_DIREC) == 0 &&
  48.          (DirEntry.ff_attrib & FA_DIREC));
  49.    }
  50. */
  51.  
  52.  
  53. void MakeFilename(const char *pszPath, const char *pszFilename, char *pszOut)
  54.    {
  55.    /* Validate parameters in debug mode */
  56. //   assert(pszPath != NULL);
  57. //   assert(pszFilename != NULL);
  58. //   assert(pszOut != NULL);
  59. //   assert(pszPath != pszOut);
  60. //   assert(pszFilename != pszOut);
  61.  
  62.    /* Copy path to output filename */
  63.    strcpy(pszOut, pszPath);
  64.  
  65.    /* Ensure there is a trailing backslash */
  66.    if(pszOut[strlen(pszOut) - 1] != '\\')
  67.       {
  68.       strcat(pszOut, "\\");
  69.       }
  70.  
  71.    /* Append base filename */
  72.    strcat(pszOut, pszFilename);
  73.    }
  74.  
  75.  
  76. tIBResult IBSendAll(tIBInfo *pInfo, char *pBuffer, int nBufferSize)
  77.    {
  78.    tIBResult ToReturn;
  79.    int iCurrentSystem;
  80.  
  81.    if(pBuffer == NULL) return(eBadParameter);
  82.  
  83.    /* Validate information structure */
  84.    ToReturn = ValidateInfoStruct(pInfo);
  85.    if(ToReturn != eSuccess) return(ToReturn);
  86.  
  87.    if(pInfo->paOtherSystem == NULL && pInfo->nTotalSystems != 0)
  88.       {
  89.       return(eBadParameter);
  90.       }
  91.  
  92.    /* Loop for each system in other systems array */
  93.    for(iCurrentSystem = 0; iCurrentSystem < pInfo->nTotalSystems;
  94.     ++iCurrentSystem)
  95.       {
  96.       /* Send information to that system */
  97.       if(strcmp(pInfo->paOtherSystem[iCurrentSystem].szAddress,pInfo->szThisNodeAddress)!=0)
  98.     {
  99.     ToReturn = IBSend(pInfo, pInfo->paOtherSystem[iCurrentSystem].szAddress,
  100.             pBuffer, nBufferSize);
  101.     if(ToReturn != eSuccess) return(ToReturn);
  102.     }
  103.       }
  104.  
  105.    return(eSuccess);
  106.    }
  107.  
  108.  
  109. tIBResult IBSend(tIBInfo *pInfo, char *pszDestNode, char *pBuffer,
  110.          int nBufferSize)
  111.    {
  112.    tIBResult ToReturn;
  113.    tMessageHeader MessageHeader;
  114.    time_t lnSecondsSince1970;
  115.    struct tm *pTimeInfo;
  116.    char szTOPT[13];
  117.    char szFMPT[13];
  118.    char szINTL[43];
  119.    char szMSGID[42];
  120.    int nKludgeSize;
  121.    int nTextSize;
  122.    char *pszMessageText;
  123.    tFidoNode DestNode;
  124.    tFidoNode OrigNode;
  125.  
  126.    if(pszDestNode == NULL) return(eBadParameter);
  127.    if(pBuffer == NULL) return(eBadParameter);
  128.  
  129.    /* Validate information structure */
  130.    ToReturn = ValidateInfoStruct(pInfo);
  131.    if(ToReturn != eSuccess) return(ToReturn);
  132.  
  133.    /* Get destination node address from string */
  134.    ConvertStringToAddress(&DestNode, pszDestNode);
  135.  
  136.    /* Get origin address from string */
  137.    ConvertStringToAddress(&OrigNode, pInfo->szThisNodeAddress);
  138.  
  139.    /* Construct message header */
  140.    /* Construct to, from and subject information */
  141.    strcpy(MessageHeader.szFromUserName, pInfo->szProgName);
  142.    strcpy(MessageHeader.szToUserName, "@NY");
  143.    strcat(MessageHeader.szToUserName, pszDestNode);
  144.    strcpy(MessageHeader.szSubject, MESSAGE_SUBJECT);
  145.  
  146.    /* Construct date and time information */
  147.    lnSecondsSince1970 = time(NULL);
  148.    pTimeInfo = localtime(&lnSecondsSince1970);
  149.    sprintf(MessageHeader.szDateTime, "%02.2d %s %02.2d  %02.2d:%02.2d:%02.2d",
  150.            pTimeInfo->tm_mday,
  151.        aszShortMonthName[pTimeInfo->tm_mon],
  152.        pTimeInfo->tm_year,
  153.            pTimeInfo->tm_hour,
  154.            pTimeInfo->tm_min,
  155.            pTimeInfo->tm_sec);
  156.  
  157.    /* Construct misc. information */
  158.    MessageHeader.wTimesRead = 0;
  159.    MessageHeader.wCost = 0;
  160.    MessageHeader.wReplyTo = 0;
  161.    MessageHeader.wNextReply = 0;
  162.  
  163.    /* Construct destination address */
  164.    MessageHeader.wDestZone = DestNode.wZone;
  165.    MessageHeader.wDestNet = DestNode.wNet;
  166.    MessageHeader.wDestNode = DestNode.wNode;
  167.    MessageHeader.wDestPoint = DestNode.wPoint;
  168.  
  169.    /* Construct origin address */
  170.    MessageHeader.wOrigZone = OrigNode.wZone;
  171.    MessageHeader.wOrigNet = OrigNode.wNet;
  172.    MessageHeader.wOrigNode = OrigNode.wNode;
  173.    MessageHeader.wOrigPoint = OrigNode.wPoint;
  174.  
  175.    /* Construct message attributes */
  176.    MessageHeader.wAttribute = ATTRIB_PRIVATE | ATTRIB_LOCAL;
  177.    if(pInfo->bCrash) MessageHeader.wAttribute |= ATTRIB_CRASH;
  178.    if(pInfo->bHold) MessageHeader.wAttribute |= ATTRIB_HOLD;
  179.    if(pInfo->bEraseOnSend) MessageHeader.wAttribute |= ATTRIB_KILL_SENT;
  180.  
  181.    /* Create message control (kludge) lines */
  182.    /* Create TOPT kludge line if destination point is non-zero */
  183.    if(DestNode.wPoint != 0)
  184.       {
  185.      sprintf(szTOPT, "\1TOPT %u\r", DestNode.wPoint);
  186.       }
  187.    else
  188.       {
  189.       strcpy(szTOPT, "");
  190.       }
  191.  
  192.    /* Create FMPT kludge line if origin point is non-zero */
  193.    if(OrigNode.wPoint != 0)
  194.       {
  195.       sprintf(szFMPT, "\1FMPT %u\r", OrigNode.wPoint);
  196.       }
  197.    else
  198.       {
  199.       strcpy(szFMPT, "");
  200.       }
  201.  
  202.    /* Create INTL kludge line if origin and destination zone addresses differ */
  203.    if(DestNode.wZone != OrigNode.wZone)
  204.       {
  205.       sprintf(szINTL, "\1INTL %u:%u/%u %u:%u/%u\r",
  206.           DestNode.wZone,
  207.           DestNode.wNet,
  208.           DestNode.wNode,
  209.           OrigNode.wZone,
  210.               OrigNode.wNet,
  211.           OrigNode.wNode);
  212.       }
  213.    else
  214.       {
  215.       strcpy(szINTL, "");
  216.       }
  217.  
  218.    /* Create MSGID kludge line, including point if non-zero */
  219.    if(OrigNode.wPoint != 0)
  220.       {
  221.       sprintf(szMSGID, "\1MSGID: %u:%u/%u.%u %lx\r",
  222.           OrigNode.wZone,
  223.               OrigNode.wNet,
  224.           OrigNode.wNode,
  225.               OrigNode.wPoint,
  226.               GetNextMSGID());
  227.       }
  228.    else
  229.       {
  230.       sprintf(szMSGID, "\1MSGID: %u:%u/%u %lx\r",
  231.           OrigNode.wZone,
  232.           OrigNode.wNet,
  233.               OrigNode.wNode,
  234.               GetNextMSGID());
  235.       }
  236.  
  237.    /* Determine total size of kludge lines */
  238.    nKludgeSize = strlen(szTOPT)
  239.                 + strlen(szFMPT)
  240.         + strlen(szINTL)
  241.         + strlen(szMSGID)
  242.                 + strlen(MESSAGE_PID);
  243.  
  244.    /* Determine total size of message text */
  245.    nTextSize = GetMaximumEncodedLength(nBufferSize)
  246.               + strlen(MESSAGE_HEADER)
  247.               + nKludgeSize
  248.           + strlen(MESSAGE_FOOTER)
  249.               + 1;
  250.  
  251.    /* Attempt to allocate space for message text */
  252.    if((pszMessageText = (char *)malloc(nTextSize)) == NULL)
  253.       {
  254.       return(eNoMemory);
  255.       }
  256.  
  257.    /* Construct message text */
  258.    strcpy(pszMessageText, szTOPT);
  259.    strcat(pszMessageText, szFMPT);
  260.    strcat(pszMessageText, szINTL);
  261.    strcat(pszMessageText, szMSGID);
  262.    strcat(pszMessageText, MESSAGE_PID);
  263.    strcat(pszMessageText, MESSAGE_HEADER);
  264.    EncodeBuffer(pszMessageText + strlen(pszMessageText), pBuffer, nBufferSize);
  265.    strcat(pszMessageText, MESSAGE_FOOTER);
  266.  
  267.    /* Attempt to send the message */
  268.    if(CreateMessage(pInfo->szNetmailDir, &MessageHeader, pszMessageText))
  269.       {
  270.       ToReturn = eSuccess;
  271.       }
  272.    else
  273.       {
  274.       ToReturn = eGeneralFailure;
  275.       }
  276.  
  277.    /* Deallocate message text buffer */
  278.    free(pszMessageText);
  279.  
  280.    /* Return appropriate value */
  281.    return(ToReturn);
  282.    }
  283.  
  284. tIBResult IBSendMail(tIBInfo *pInfo, ibbs_mail_type *ibmail)
  285.    {
  286.    tIBResult ToReturn;
  287.    tMessageHeader MessageHeader;
  288.    time_t lnSecondsSince1970;
  289.    struct tm *pTimeInfo;
  290.    char szTOPT[13];
  291.    char szFMPT[13];
  292.    char szINTL[43];
  293.    char szMSGID[42];
  294.    int nKludgeSize;
  295.    int nTextSize;
  296.    char *pszMessageText;
  297.    tFidoNode DestNode;
  298.    tFidoNode OrigNode;
  299.  
  300.    if(ibmail->node_r == NULL) return(eBadParameter);
  301.    if(ibmail == NULL) return(eBadParameter);
  302.  
  303.    /* Validate information structure */
  304.    ToReturn = ValidateInfoStruct(pInfo);
  305.    if(ToReturn != eSuccess) return(ToReturn);
  306.  
  307.    /* Get destination node address from string */
  308.    ConvertStringToAddress(&DestNode, ibmail->node_r);
  309.  
  310.    /* Get origin address from string */
  311.    ConvertStringToAddress(&OrigNode, pInfo->szThisNodeAddress);
  312.  
  313.  
  314.    /* Construct message header */
  315.    /* Construct to, from and subject information */
  316.    strcpy(MessageHeader.szFromUserName, pInfo->szProgName);
  317.    strcpy(MessageHeader.szToUserName, "@NY");
  318.    strcat(MessageHeader.szToUserName, ibmail->node_r);
  319.    strcpy(MessageHeader.szSubject, MESSAGE_SUBJECT);
  320.  
  321.  
  322.    /* Construct date and time information */
  323.    lnSecondsSince1970 = time(NULL);
  324.    pTimeInfo = localtime(&lnSecondsSince1970);
  325.    sprintf(MessageHeader.szDateTime, "%02.2d %s %02.2d  %02.2d:%02.2d:%02.2d",
  326.        pTimeInfo->tm_mday,
  327.        aszShortMonthName[pTimeInfo->tm_mon],
  328.        pTimeInfo->tm_year,
  329.        pTimeInfo->tm_hour,
  330.        pTimeInfo->tm_min,
  331.        pTimeInfo->tm_sec);
  332.  
  333.    /* Construct misc. information */
  334.    MessageHeader.wTimesRead = 0;
  335.    MessageHeader.wCost = 0;
  336.    MessageHeader.wReplyTo = 0;
  337.    MessageHeader.wNextReply = 0;
  338.  
  339.    /* Construct destination address */
  340.    MessageHeader.wDestZone = DestNode.wZone;
  341.    MessageHeader.wDestNet = DestNode.wNet;
  342.    MessageHeader.wDestNode = DestNode.wNode;
  343.    MessageHeader.wDestPoint = DestNode.wPoint;
  344.  
  345.    /* Construct origin address */
  346.    MessageHeader.wOrigZone = OrigNode.wZone;
  347.    MessageHeader.wOrigNet = OrigNode.wNet;
  348.    MessageHeader.wOrigNode = OrigNode.wNode;
  349.    MessageHeader.wOrigPoint = OrigNode.wPoint;
  350.  
  351.    /* Construct message attributes */
  352.    MessageHeader.wAttribute = ATTRIB_PRIVATE | ATTRIB_LOCAL;
  353.    if(pInfo->bCrash) MessageHeader.wAttribute |= ATTRIB_CRASH;
  354.    if(pInfo->bHold) MessageHeader.wAttribute |= ATTRIB_HOLD;
  355.    if(pInfo->bEraseOnSend) MessageHeader.wAttribute |= ATTRIB_KILL_SENT;
  356.  
  357.  
  358.    /* Create message control (kludge) lines */
  359.    /* Create TOPT kludge line if destination point is non-zero */
  360.    if(DestNode.wPoint != 0)
  361.       {
  362.      sprintf(szTOPT, "\1TOPT %u\r", DestNode.wPoint);
  363.       }
  364.    else
  365.       {
  366.       strcpy(szTOPT, "");
  367.       }
  368.  
  369.    /* Create FMPT kludge line if origin point is non-zero */
  370.    if(OrigNode.wPoint != 0)
  371.       {
  372.       sprintf(szFMPT, "\1FMPT %u\r", OrigNode.wPoint);
  373.       }
  374.    else
  375.       {
  376.       strcpy(szFMPT, "");
  377.       }
  378.  
  379.    /* Create INTL kludge line if origin and destination zone addresses differ */
  380.    if(DestNode.wZone != OrigNode.wZone)
  381.       {
  382.       sprintf(szINTL, "\1INTL %u:%u/%u %u:%u/%u\r",
  383.           DestNode.wZone,
  384.           DestNode.wNet,
  385.           DestNode.wNode,
  386.           OrigNode.wZone,
  387.           OrigNode.wNet,
  388.           OrigNode.wNode);
  389.       }
  390.    else
  391.       {
  392.       strcpy(szINTL, "");
  393.       }
  394.  
  395.    /* Create MSGID kludge line, including point if non-zero */
  396.    if(OrigNode.wPoint != 0)
  397.       {
  398.       sprintf(szMSGID, "\1MSGID: %u:%u/%u.%u %lx\r",
  399.           OrigNode.wZone,
  400.           OrigNode.wNet,
  401.           OrigNode.wNode,
  402.           OrigNode.wPoint,
  403.           GetNextMSGID());
  404.       }
  405.    else
  406.       {
  407.       sprintf(szMSGID, "\1MSGID: %u:%u/%u %lx\r",
  408.           OrigNode.wZone,
  409.           OrigNode.wNet,
  410.           OrigNode.wNode,
  411.           GetNextMSGID());
  412.       }
  413.  
  414.    /* Determine total size of kludge lines */
  415.    nKludgeSize = strlen(szTOPT)
  416.         + strlen(szFMPT)
  417.         + strlen(szINTL)
  418.         + strlen(szMSGID)
  419.         + strlen(MESSAGE_PID);
  420.  
  421.  
  422.    /* Determine total size of message text */
  423.    nTextSize = sizeof(ibbs_mail_type) * 2 + 4 * 20 + 1
  424.           + strlen(MESSAGE_HEADER)
  425.           + nKludgeSize
  426.           + strlen(MESSAGE_FOOTER)
  427.           + 1;
  428.  
  429.  
  430.    /* Attempt to allocate space for message text */
  431.    if((pszMessageText = (char *)malloc(nTextSize)) == NULL)
  432.       {
  433.       return(eNoMemory);
  434.       }
  435.  
  436.    /* Construct message text */
  437.    strcpy(pszMessageText, szTOPT);
  438.    strcat(pszMessageText, szFMPT);
  439.    strcat(pszMessageText, szINTL);
  440.    strcat(pszMessageText, szMSGID);
  441.    strcat(pszMessageText, MESSAGE_PID);
  442.    strcat(pszMessageText, MESSAGE_HEADER);
  443.  
  444.  
  445.    EncodeMail(pszMessageText + strlen(pszMessageText),ibmail);
  446. //   EncodeBuffer(pszMessageText + strlen(pszMessageText), pBuffer, nBufferSize);
  447.    strcat(pszMessageText, MESSAGE_FOOTER);
  448.  
  449.  
  450.    /* Attempt to send the message */
  451.    if(CreateMessage(pInfo->szNetmailDir, &MessageHeader, pszMessageText))
  452.       {
  453.       ToReturn = eSuccess;
  454.       }
  455.    else
  456.       {
  457.       ToReturn = eGeneralFailure;
  458.       }
  459.  
  460.  
  461.    /* Deallocate message text buffer */
  462.    free(pszMessageText);
  463.  
  464.  
  465.    /* Return appropriate value */
  466.    return(ToReturn);
  467.    }
  468.  
  469.  
  470.  
  471. int GetMaximumEncodedLength(int nUnEncodedLength)
  472.    {
  473.    int nEncodedLength;
  474.  
  475.    /* The current encoding algorithm uses two characters to represent   */
  476.    /* each byte of data, plus 1 byte per MAX_LINE_LENGTH characters for */
  477.    /* the carriage return character.                                    */
  478.  
  479.    nEncodedLength = nUnEncodedLength * 2;
  480.  
  481.    return(nEncodedLength + (nEncodedLength / MAX_LINE_LENGTH - 1) + 1);
  482.    }
  483.  
  484.  
  485. void EncodeBuffer(char *pszDest, const char *pBuffer, int nBufferSize)
  486.    {
  487.    int iSourceLocation;
  488.    int nOutputChars = 0;
  489.    char *pcDest = pszDest;
  490.    const char *pcSource = (char *)pBuffer;
  491.  
  492.    /* Loop for each byte of the source buffer */
  493.    for(iSourceLocation = 0; iSourceLocation < nBufferSize; ++iSourceLocation)
  494.       {
  495.       /* First character contains bits 0 - 5, with 01 in upper two bits */
  496.       *pcDest++ = (*pcSource & 0x3f) | 0x40;
  497.       /* Second character contains bits 6 & 7 in positions 4 & 5. Upper */
  498.       /* two bits are 01, and all remaining bits are 0. */
  499.       *pcDest++ = ((*pcSource & 0xc0) >> 2) | 0x40;
  500.  
  501.       /* Output carriage return when needed */
  502.       if((nOutputChars += 2) >= MAX_LINE_LENGTH - 1)
  503.          {
  504.      nOutputChars = 0;
  505.      *pcDest++ = '\r';
  506.      }
  507.  
  508.       /* Increment source pointer */
  509.       ++pcSource;
  510.       }
  511.  
  512.    /* Add one last carriage return, regardless of what has come before */
  513.    *pcDest++ = '\r';
  514.  
  515.    /* Terminate output string */
  516.    *pcDest++ = '\0';
  517.    }
  518.  
  519. void EncodeMail(char *pszDest,ibbs_mail_type *ibmail)
  520. {
  521.    char *pcDest = pszDest;
  522.    int x,l,ln;
  523.    char temp[25];
  524.  
  525.    l=strlen(ibmail->sender);
  526.    for(x=0;x<l;x++) {
  527.      sprintf(pcDest,"%02X",(int)ibmail->sender[x]);
  528.      pcDest+=2;
  529.    }
  530.    *pcDest='\n';
  531.    pcDest++;
  532.  
  533.    l=strlen(ibmail->senderI);
  534.    for(x=0;x<l;x++) {
  535.      sprintf(pcDest,"%02X",(int)ibmail->senderI[x]);
  536.      pcDest+=2;
  537.    }
  538.    *pcDest='\n';
  539.    pcDest++;
  540.  
  541.  
  542.    sprintf(pcDest,"%X",(int)ibmail->sender_sex);
  543.    pcDest+=strlen(pcDest);
  544.  
  545.    *pcDest='\n';
  546.    pcDest++;
  547.  
  548.    l=strlen(ibmail->node_s);
  549.    for(x=0;x<l;x++) {
  550.      sprintf(pcDest,"%02X",(int)ibmail->node_s[x]);
  551.      pcDest+=2;
  552.    }
  553.    *pcDest='\n';
  554.    pcDest++;
  555.  
  556.    l=strlen(ibmail->node_r);
  557.    for(x=0;x<l;x++) {
  558.      sprintf(pcDest,"%02X",(int)ibmail->node_r[x]);
  559.      pcDest+=2;
  560.    }
  561.    *pcDest='\n';
  562.    pcDest++;
  563.  
  564.    l=strlen(ibmail->recver);
  565.    for(x=0;x<l;x++) {
  566.      sprintf(pcDest,"%02X",(int)ibmail->recver[x]);
  567.      pcDest+=2;
  568.    }
  569.    *pcDest='\n';
  570.    pcDest++;
  571.  
  572.    l=strlen(ibmail->recverI);
  573.    for(x=0;x<l;x++) {
  574.      sprintf(pcDest,"%02X",(int)ibmail->recverI[x]);
  575.      pcDest+=2;
  576.    }
  577.    *pcDest='\n';
  578.    pcDest++;
  579.  
  580.    sprintf(pcDest,"%X",(int)ibmail->quote_length);
  581.    pcDest+=strlen(pcDest);
  582.  
  583.    *pcDest='\n';
  584.    pcDest++;
  585.  
  586.    sprintf(pcDest,"%X",(int)ibmail->length);
  587.    pcDest+=strlen(pcDest);
  588.  
  589.    *pcDest='\n';
  590.    pcDest++;
  591.  
  592.    sprintf(pcDest,"%X",(int)ibmail->flirt);
  593.    pcDest+=strlen(pcDest);
  594.  
  595.    *pcDest='\n';
  596.    pcDest++;
  597.  
  598.  
  599.    sprintf(pcDest,"%X",(int)ibmail->ill);
  600.    pcDest+=strlen(pcDest);
  601.  
  602.    *pcDest='\n';
  603.    pcDest++;
  604.  
  605.    sprintf(pcDest,"%X",(int)ibmail->inf);
  606.    pcDest+=strlen(pcDest);
  607.  
  608.    *pcDest='\n';
  609.    pcDest++;
  610.  
  611.    for(ln=0;ln<(ibmail->length + ibmail->quote_length) && ln<20;ln++) {
  612.      l=strlen(ibmail->lines[ln]);
  613.      if(l==0) {
  614.        *pcDest='0';
  615.        pcDest++;
  616.        *pcDest='0';
  617.        pcDest++;
  618.      }
  619.  
  620.      for(x=0;x<l && x<20 ;x++) {
  621.        sprintf(pcDest,"%02X",(int)ibmail->lines[ln][x]);
  622.        pcDest+=2;
  623.      }
  624.  
  625.      *pcDest='\n';
  626.      pcDest++;
  627.  
  628.      if(l<=20) {
  629.        *pcDest='0';
  630.        pcDest++;
  631.        *pcDest='0';
  632.        pcDest++;
  633.      }
  634.  
  635.      for(x=20;x<l && x<40;x++) {
  636.        sprintf(pcDest,"%02X",(int)ibmail->lines[ln][x]);
  637.        pcDest+=2;
  638.      }
  639.      *pcDest='\n';
  640.      pcDest++;
  641.  
  642.      if(l<=40) {
  643.        *pcDest='0';
  644.        pcDest++;
  645.        *pcDest='0';
  646.        pcDest++;
  647.      }
  648.  
  649.      for(x=40;x<l && x<60;x++) {
  650.        sprintf(pcDest,"%02X",(int)ibmail->lines[ln][x]);
  651.        pcDest+=2;
  652.      }
  653.  
  654.      *pcDest='\n';
  655.      pcDest++;
  656.  
  657.  
  658.      if(l<=60) {
  659.        *pcDest='0';
  660.        pcDest++;
  661.        *pcDest='0';
  662.        pcDest++;
  663.      }
  664.      for(x=60;x<l;x++) {
  665.        sprintf(pcDest,"%02X",(int)ibmail->lines[ln][x]);
  666.        pcDest+=2;
  667.      }
  668.      *pcDest='\n';
  669.      pcDest++;
  670.    }
  671.    *pcDest = '\0';
  672. }
  673.  
  674. /*
  675. void DecodeBuffer(const char *pszSource, void *pDestBuffer, int nBufferSize)
  676.    {
  677.    const char *pcSource = pszSource;
  678.    char *pcDest = (char *)pDestBuffer;
  679.    int iDestLocation;
  680.    tBool bFirstOfByte = TRUE;
  681.  
  682.    /* Search for beginning of buffer delimiter char, returning if not found -/
  683.    while(*pcSource && *pcSource != DELIMITER_CHAR) ++pcSource;
  684.    if(!*pcSource) return;
  685.  
  686.    /* Move pointer to first char after delimiter char -/
  687.    ++pcSource;
  688.  
  689.    /* Loop until destination buffer is full, delimiter char is encountered, -/
  690.    /* or end of source buffer is encountered -/
  691.    iDestLocation = 0;
  692.    while(iDestLocation < nBufferSize && *pcSource
  693.     && *pcSource != DELIMITER_CHAR)
  694.       {
  695.       /* If this is a valid data character -/
  696.       if(*pcSource >= 0x40 && *pcSource <= 0x7e)
  697.      {
  698.      /* If this is first character of byte -/
  699.      if(bFirstOfByte)
  700.         {
  701.         *pcDest = *pcSource & 0x3f;
  702.  
  703.         /* Toggle bFirstOfByte -/
  704.         bFirstOfByte = FALSE;
  705.         }
  706.      else /* if(!bFirstOfByte) -/
  707.         {
  708.         *pcDest |= (*pcSource & 0x30) << 2;
  709.  
  710.         /* Increment destination -/
  711.         ++iDestLocation;
  712.         ++pcDest;
  713.  
  714.         /* Toggle bFirstOfByte -/
  715.         bFirstOfByte = TRUE;
  716.         }
  717.      }
  718.  
  719.       /* Increment source byte pointer -/
  720.       ++pcSource;
  721.       }
  722.    }
  723. */
  724.  
  725. void DecodeMail(const char *pszSource, ibbs_mail_type *ibmail)
  726. {
  727.    const char *pcSource = pszSource;
  728.    int x,ln,t;
  729.    char tmp[80];//,key;
  730.  
  731. //   tmp[2]=0;
  732.    x=0;
  733.  
  734. //   printf("1\n");
  735. //   scanf("%c",&key);
  736.    while(*pcSource && *pcSource != DELIMITER_CHAR) ++pcSource;
  737.    if(!(*pcSource)) return;
  738. //   printf("2\n");
  739. //   scanf("%c",&key);
  740.    pcSource++;
  741.  
  742.   // printf("3\n");
  743. //   scanf("%c",&key);
  744.    while(*pcSource<=' ')
  745.      pcSource++;
  746.  
  747. //     printf("4\n");
  748. //     scanf("%c",&key);
  749.    while(*pcSource>' ') {
  750.      tmp[0]=*pcSource;
  751.      tmp[1]=*(pcSource+1);
  752.      tmp[2]=0;
  753.      sscanf(tmp,"%X",&t);
  754.      ibmail->sender[x]=t;
  755.      pcSource+=2;
  756.      x++;
  757.    }
  758.    ibmail->sender[x]=0;
  759.  
  760. //   printf("5\n");
  761. //   scanf("%c",&key);
  762.    while(*pcSource<=' ')
  763.      pcSource++;
  764.  
  765. //   tmp[2]=0;
  766.    x=0;
  767.    while(*pcSource>' ') {
  768.      tmp[0]=*pcSource;
  769.      tmp[1]=*(pcSource+1);
  770.      tmp[2]=0;
  771.      sscanf(tmp,"%X",&t);
  772.      ibmail->senderI[x]=t;
  773.      pcSource+=2;
  774.      x++;
  775.    }
  776. //   printf("6\n");
  777. //   scanf("%c",&key);
  778.    ibmail->senderI[x]=0;
  779.  
  780.    while(*pcSource<=' ')
  781.      pcSource++;
  782.  
  783.    sscanf(pcSource,"%s",&tmp);
  784.    pcSource+=strlen(tmp);
  785.    sscanf(tmp,"%X",&t);
  786.    ibmail->sender_sex=(sex_type)t;
  787.  
  788.    while(*pcSource<=' ')
  789.      pcSource++;
  790.  
  791.    tmp[2]=0;
  792.    x=0;
  793.    while(*pcSource>' ') {
  794.      tmp[0]=*pcSource;
  795.      tmp[1]=*(pcSource+1);
  796.      sscanf(tmp,"%X",&t);
  797.      ibmail->node_s[x]=t;
  798.      pcSource+=2;
  799.      x++;
  800.    }
  801.    ibmail->node_s[x]=0;
  802. //   printf("[%s]",ibmail->node_s); //debug
  803.  
  804. //   printf("7\n");
  805. //   scanf("%c",&key);
  806.  
  807.    while(*pcSource<=' ')
  808.      pcSource++;
  809.  
  810.    tmp[2]=0;
  811.    x=0;
  812.    while(*pcSource>' ') {
  813.      tmp[0]=*pcSource;
  814.      tmp[1]=*(pcSource+1);
  815.      sscanf(tmp,"%X",&t);
  816.      ibmail->node_r[x]=t;
  817.      pcSource+=2;
  818.      x++;
  819.    }
  820.    ibmail->node_r[x]=0;
  821. //   printf("[%s]",ibmail->node_r); //debug
  822.  
  823.    while(*pcSource<=' ')
  824.      pcSource++;
  825.  
  826.    tmp[2]=0;
  827.    x=0;
  828.    while(*pcSource>' ') {
  829.      tmp[0]=*pcSource;
  830.      tmp[1]=*(pcSource+1);
  831.      sscanf(tmp,"%X",&t);
  832.      ibmail->recver[x]=t;
  833.      pcSource+=2;
  834.      x++;
  835.    }
  836.    ibmail->recver[x]=0;
  837.    while(*pcSource<=' ')
  838.      pcSource++;
  839.  
  840.    tmp[2]=0;
  841.    x=0;
  842.    while(*pcSource>' ') {
  843.      tmp[0]=*pcSource;
  844.      tmp[1]=*(pcSource+1);
  845.      sscanf(tmp,"%X",&t);
  846.      ibmail->recverI[x]=t;
  847.      pcSource+=2;
  848.      x++;
  849.    }
  850.    ibmail->recverI[x]=0;
  851.    while(*pcSource<=' ')
  852.      pcSource++;
  853.  
  854.    sscanf(pcSource,"%s",&tmp);
  855.    pcSource+=strlen(tmp);
  856.    sscanf(tmp,"%X",&t);
  857.    ibmail->quote_length=t;
  858. //   printf("[QL%d]",(int)ibmail->quote_length); //debug
  859.  
  860.    while(*pcSource<=' ')
  861.      pcSource++;
  862.  
  863.    sscanf(pcSource,"%s",&tmp);
  864.    pcSource+=strlen(tmp);
  865.    sscanf(tmp,"%X",&t);
  866.    ibmail->length=t;
  867. //   printf("[L%d]",(int)ibmail->length); //debug
  868.  
  869.    while(*pcSource<=' ')
  870.      pcSource++;
  871.  
  872.    sscanf(pcSource,"%s",&tmp);
  873.    pcSource+=strlen(tmp);
  874.    sscanf(tmp,"%X",&t);
  875.    ibmail->flirt=t;
  876. //   printf("[F%d][%s]",(int)ibmail->flirt,tmp); //debug
  877.  
  878.    while(*pcSource<=' ')
  879.      pcSource++;
  880.  
  881.  
  882.    sscanf(pcSource,"%s",&tmp);
  883.    pcSource+=strlen(tmp);
  884.    sscanf(tmp,"%X",&t);
  885.    ibmail->ill=(desease)t;
  886. //   printf("[D%d]",(int)ibmail->ill); //debug
  887.  
  888.    while(*pcSource<=' ')
  889.      pcSource++;
  890.  
  891.    sscanf(pcSource,"%s",&tmp);
  892.    pcSource+=strlen(tmp);
  893.    sscanf(tmp,"%X",&t);
  894.    ibmail->inf=t;
  895. //   printf("[INF%d]\n",(int)ibmail->inf); //debug
  896.  
  897.    while(*pcSource<=' ')
  898.      pcSource++;
  899.  
  900. //   printf("8\n");
  901. //   scanf("%c",&key);
  902.  
  903.    for(ln=0;ln<(ibmail->length + ibmail->quote_length) && ln<20;ln++) {
  904.      tmp[2]=0;
  905.      x=0;
  906.      while(*pcSource>' ') {
  907.        tmp[0]=*pcSource;
  908.        tmp[1]=*(pcSource+1);
  909.        sscanf(tmp,"%X",&t);
  910.        (ibmail->lines)[ln][x]=t;
  911.        pcSource+=2;
  912.        x++;
  913.        if(x>80) break;
  914.      }
  915.      while(*pcSource<=' ')
  916.        pcSource++;
  917.  
  918.      while(*pcSource>' ') {
  919.        tmp[0]=*pcSource;
  920.        tmp[1]=*(pcSource+1);
  921.        sscanf(tmp,"%X",&t);
  922.        (ibmail->lines)[ln][x]=t;
  923.        pcSource+=2;
  924.        x++;
  925.        if(x>80) break;
  926.      }
  927.  
  928.      while(*pcSource<=' ')
  929.        pcSource++;
  930.  
  931.      while(*pcSource>' ') {
  932.        tmp[0]=*pcSource;
  933.        tmp[1]=*(pcSource+1);
  934.        sscanf(tmp,"%X",&t);
  935.        (ibmail->lines)[ln][x]=t;
  936.        pcSource+=2;
  937.        x++;
  938.        if(x>80) break;
  939.      }
  940.      while(*pcSource<=' ')
  941.        pcSource++;
  942.  
  943.      while(*pcSource>' ') {
  944.        tmp[0]=*pcSource;
  945.        tmp[1]=*(pcSource+1);
  946.        sscanf(tmp,"%X",&t);
  947.        (ibmail->lines)[ln][x]=t;
  948.        pcSource+=2;
  949.        x++;
  950.        if(x>80) break;
  951.      }
  952.      (ibmail->lines)[ln][x]=0;
  953.      while(*pcSource<=' ')
  954.        pcSource++;
  955.    }
  956. //   printf("9\n");
  957. //   scanf("%c",&key);
  958. //   return;
  959. }
  960.  
  961.  
  962. /*int DecodeBufferR(const char *pszSource, void *pDestBuffer)
  963.    {
  964.    const char *pcSource = pszSource;
  965.    char *pcDest = (char *)pDestBuffer;
  966.    char *size[2];
  967.    int iDestLocation;
  968.    int nBufferSize=0;
  969.    tBool bFirstOfByte = TRUE;
  970.  
  971.    /* Search for beginning of buffer delimiter char, returning if not found -/
  972.    while(*pcSource && *pcSource != DELIMITER_CHAR) ++pcSource;
  973.    if(!*pcSource) return(0);
  974.  
  975.    /* Move pointer to first char after delimiter char -/
  976.    ++pcSource;
  977.  
  978.    /* Loop until destination buffer is full, delimiter char is encountered, -/
  979.    /* or end of source buffer is encountered -/
  980.    iDestLocation = 0;
  981.    while(iDestLocation < (nBufferSize+2) && *pcSource
  982.     && *pcSource != DELIMITER_CHAR)
  983.       {
  984.       /* If this is a valid data character -/
  985.       if(*pcSource >= 0x40 && *pcSource <= 0x7e)
  986.      {
  987.      /* If this is first character of byte -/
  988.      if(bFirstOfByte)
  989.         {
  990.         if(iDestLocation<2)
  991.           *size[iDestLocation] = *pcSource & 0x3f;
  992.         else
  993.           *pcDest = *pcSource & 0x3f;
  994.  
  995.         /* Toggle bFirstOfByte -/
  996.         bFirstOfByte = FALSE;
  997.         }
  998.      else /* if(!bFirstOfByte) -/
  999.         {
  1000.         if(iDestLocation<2)
  1001.           *size[iDestLocation] |= (*pcSource & 0x30) << 2;
  1002.         else
  1003.           {
  1004.           *pcDest |= (*pcSource & 0x30) << 2;
  1005.           ++pcDest;
  1006.           }
  1007.  
  1008.         /* Increment destination -/
  1009.         ++iDestLocation;
  1010.  
  1011.         /* Toggle bFirstOfByte -/
  1012.         bFirstOfByte = TRUE;
  1013.         }
  1014.      if(iDestLocation==2)
  1015.        {
  1016.        nBufferSize=*(int *)size;
  1017.        pDestBuffer=malloc(nBufferSize);
  1018.        }
  1019.      }
  1020.       /* Increment source byte pointer -/
  1021.       ++pcSource;
  1022.       }
  1023.    return(nBufferSize);
  1024.    }
  1025. */
  1026.  
  1027.  
  1028. DWORD GetNextMSGID(void)
  1029.    {
  1030.    /* MSGID should be unique for every message, for as long as possible.   */
  1031.    /* This technique adds the current time, in seconds since midnight on   */
  1032.    /* January 1st, 1970 to a psuedo-random number. The random generator    */
  1033.    /* is not seeded, as the application may have already seeded it for its */
  1034.    /* own purposes. Even if not seeded, the inclusion of the current time  */
  1035.    /* will cause the MSGID to almost always be different.                  */
  1036.    return((DWORD)time(NULL) + (DWORD)rand());
  1037.    }
  1038.  
  1039.  
  1040. tBool CreateMessage(char *pszMessageDir, tMessageHeader *pHeader,
  1041.             char *pszText)
  1042.    {
  1043.    DWORD lwNewMsgNum;
  1044.  
  1045.    /* Get new message number */
  1046.    lwNewMsgNum = GetFirstUnusedMsgNum(pszMessageDir);
  1047.  
  1048.    /* Use WriteMessage() to create new message */
  1049.    return(WriteMessage(pszMessageDir, lwNewMsgNum, pHeader, pszText));
  1050.    }
  1051.  
  1052.  
  1053. void GetMessageFilename(char *pszMessageDir, DWORD lwMessageNum,
  1054.             char *pszOut)
  1055.    {
  1056.    char szFileName[FILENAME_CHARS + 1];
  1057.  
  1058.    sprintf(szFileName, "%ld.msg", lwMessageNum);
  1059.    MakeFilename(pszMessageDir, szFileName, pszOut);
  1060.    }
  1061.  
  1062.  
  1063. tBool WriteMessage(char *pszMessageDir, DWORD lwMessageNum,
  1064.            tMessageHeader *pHeader, char *pszText)
  1065.    {
  1066.    char szFileName[PATH_CHARS + FILENAME_CHARS + 2];
  1067.    int hFile;
  1068.    size_t nTextSize;
  1069.  
  1070.    /* Get fully qualified filename of message to write */
  1071.    GetMessageFilename(pszMessageDir, lwMessageNum, szFileName);
  1072.  
  1073.    /* Open message file */
  1074.    hFile = open(szFileName, O_WRONLY|O_BINARY|O_CREAT|O_DENYALL,
  1075.                 S_IREAD|S_IWRITE);
  1076.  
  1077.    /* If open failed, return FALSE */
  1078.    if(hFile == -1) return(FALSE);
  1079.  
  1080.    /* Attempt to write header */
  1081.    if(write(hFile, pHeader, sizeof(tMessageHeader)) != sizeof(tMessageHeader))
  1082.       {
  1083.       /* On failure, close file, erase file, and return FALSE */
  1084.       close(hFile);
  1085.       unlink(szFileName);
  1086.       return(FALSE);
  1087.       }
  1088.  
  1089.    /* Determine size of message text, including string terminator */
  1090.    nTextSize = strlen(pszText) + 1;
  1091.  
  1092.    /* Attempt to write message text */
  1093.    if(write(hFile, pszText, nTextSize) != nTextSize)
  1094.       {
  1095.       /* On failure, close file, erase file, and return FALSE */
  1096.       close(hFile);
  1097.       unlink(szFileName);
  1098.       return(FALSE);
  1099.       }
  1100.  
  1101.    /* Close message file */
  1102.    close(hFile);
  1103.  
  1104.    /* Return with success */
  1105.    return(TRUE);
  1106.    }
  1107.  
  1108.  
  1109. tBool ReadMessage(char *pszMessageDir, DWORD lwMessageNum,
  1110.                   tMessageHeader *pHeader, char **ppszText)
  1111.    {
  1112.    char szFileName[PATH_CHARS + FILENAME_CHARS + 2];
  1113.    int hFile;
  1114.    size_t nTextSize;
  1115.  
  1116.    /* Get fully qualified filename of message to read */
  1117.    GetMessageFilename(pszMessageDir, lwMessageNum, szFileName);
  1118.  
  1119.    /* Open message file */
  1120.    hFile = open(szFileName, O_RDONLY|O_BINARY|O_DENYWRITE);
  1121.  
  1122.    /* If open failed, return FALSE */
  1123.    if(hFile == -1) return(FALSE);
  1124.  
  1125.    /* Determine size of message body */
  1126.    nTextSize = (size_t)filelength(hFile) - sizeof(tMessageHeader);
  1127.  
  1128.    /* Attempt to allocate space for message body, plus character for added */
  1129.    /* string terminator.                                                   */
  1130.    if((*ppszText = (char *)malloc(nTextSize + 1)) == NULL)
  1131.       {
  1132.       /* On failure, close file and return FALSE */
  1133.       close(hFile);
  1134.       return(FALSE);
  1135.       }
  1136.  
  1137.    /* Attempt to read header */
  1138.    if(read(hFile, pHeader, sizeof(tMessageHeader)) != sizeof(tMessageHeader))
  1139.       {
  1140.       /* On failure, close file, deallocate message buffer and return FALSE */
  1141.       close(hFile);
  1142.       free(*ppszText);
  1143.       return(FALSE);
  1144.       }
  1145.  
  1146.    /* Attempt to read message text */
  1147.    if(read(hFile, *ppszText, nTextSize) != nTextSize)
  1148.       {
  1149.       /* On failure, close file, deallocate message buffer and return FALSE */
  1150.       close(hFile);
  1151.       free(*ppszText);
  1152.       return(FALSE);
  1153.       }
  1154.  
  1155.    /* Ensure that message buffer is NULL-terminated */
  1156.    (*ppszText)[nTextSize + 1] = '\0';
  1157.  
  1158.    /* Close message file */
  1159.    close(hFile);
  1160.  
  1161.    /* Return with success */
  1162.    return(TRUE);
  1163.    }
  1164.  
  1165.  
  1166. DWORD GetFirstUnusedMsgNum(char *pszMessageDir)
  1167.    {
  1168.    DWORD lwHighestMsgNum = 0;
  1169.    DWORD lwCurrentMsgNum;
  1170.    struct ffblk DirEntry;
  1171.    char szFileName[PATH_CHARS + FILENAME_CHARS + 2];
  1172.  
  1173.    MakeFilename(pszMessageDir, "*.msg", szFileName);
  1174.  
  1175.    if(findfirst(szFileName, &DirEntry, FA_ARCH) == 0)
  1176.       {
  1177.       do
  1178.      {
  1179.      lwCurrentMsgNum = atol(DirEntry.ff_name);
  1180.      if(lwCurrentMsgNum > lwHighestMsgNum)
  1181.         {
  1182.         lwHighestMsgNum = lwCurrentMsgNum;
  1183.         }
  1184.      } while(findnext(&DirEntry) == 0);
  1185.       }
  1186.  
  1187.    return(lwHighestMsgNum + 1);
  1188.    }
  1189.  
  1190.  
  1191. tIBResult ValidateInfoStruct(tIBInfo *pInfo)
  1192.    {
  1193.    if(pInfo == NULL) return(eBadParameter);
  1194.  
  1195. //   if(!DirExists(pInfo->szNetmailDir)) return(eMissingDir);
  1196.  
  1197.    if(strlen(pInfo->szProgName) == 0) return(eBadParameter);
  1198.  
  1199.    return(eSuccess);
  1200.    }
  1201.  
  1202.  
  1203. /*tIBResult IBGet(tIBInfo *pInfo, void *pBuffer, int nMaxBufferSize)
  1204.    {
  1205.    tIBResult ToReturn;
  1206.    struct ffblk DirEntry;
  1207.    DWORD lwCurrentMsgNum;
  1208.    tMessageHeader MessageHeader;
  1209.    char szFileName[PATH_CHARS + FILENAME_CHARS + 2];
  1210.    char *pszText;
  1211.    tFidoNode ThisNode,OtherNode;
  1212.  
  1213.    /* Validate information structure -/
  1214.    ToReturn = ValidateInfoStruct(pInfo);
  1215.    if(ToReturn != eSuccess) return(ToReturn);
  1216.  
  1217.    /* Get this node's address from string -/
  1218.    ConvertStringToAddress(&ThisNode, pInfo->szThisNodeAddress);
  1219.  
  1220.    MakeFilename(pInfo->szNetmailDir, "*.msg", szFileName);
  1221.  
  1222.    /* Seach through each message file in the netmail directory, in no -/
  1223.    /* particular order.                                               -/
  1224.    if(findfirst(szFileName, &DirEntry, FA_ARCH) == 0)
  1225.       {
  1226.       do
  1227.      {
  1228.      lwCurrentMsgNum = atol(DirEntry.ff_name);
  1229.  
  1230.      /* If able to read message -/
  1231.      if(ReadMessage(pInfo->szNetmailDir, lwCurrentMsgNum, &MessageHeader,
  1232.         &pszText))
  1233.         {
  1234. /*        od_printf("\n\rREAD THROUGH MESSAGE\n\r");
  1235.         od_printf("|%s|\n\r",MessageHeader.szToUserName);
  1236.         od_printf("|%s|\n\r",pInfo->szProgName);
  1237.         od_printf("%d:",MessageHeader.wDestZone);
  1238.         od_printf("%d/",MessageHeader.wDestNet);
  1239.         od_printf("%d.",MessageHeader.wDestNode);
  1240.         od_printf("%d\n\r",MessageHeader.wDestPoint);
  1241.  
  1242.         od_get_answer("1");*/
  1243.         /* If message is for us, and hasn't be read yet -/
  1244.         ConvertStringToAddress(&OtherNode,&MessageHeader.szToUserName[3]);
  1245.  
  1246.         if(strcmp(MessageHeader.szFromUserName, pInfo->szProgName) == 0
  1247.            && (ThisNode.wZone == OtherNode.wZone || OtherNode.wZone==0 || ThisNode.wZone==0)
  1248.            && ThisNode.wNet == OtherNode.wNet
  1249.            && ThisNode.wNode == OtherNode.wNode
  1250.            && ThisNode.wPoint == OtherNode.wPoint
  1251.            && !(MessageHeader.wAttribute & ATTRIB_RECEIVED))
  1252.            {
  1253.  
  1254. /*           od_printf("\n\rUNREAD AND FOR US\n\r");
  1255.            od_get_answer("1");*/
  1256.  
  1257.            /* Decode message text, placing information in buffer -/
  1258.            DecodeBuffer(pszText, pBuffer, nMaxBufferSize);
  1259.  
  1260.            /* If received messages should be deleted -/
  1261.            if(pInfo->bEraseOnReceive)
  1262.           {
  1263.           /* Determine filename of message to erase -/
  1264.           GetMessageFilename(pInfo->szNetmailDir, lwCurrentMsgNum,
  1265.                      szFileName);
  1266.  
  1267.           /* Attempt to erase file -/
  1268.           if(unlink(szFileName) == -1)
  1269.              {
  1270.              ToReturn = eGeneralFailure;
  1271.              }
  1272.           else
  1273.              {
  1274.              ToReturn = eSuccess;
  1275.              }
  1276.           }
  1277.  
  1278.            /* If received messages should not be deleted -/
  1279.            else /* if(!pInfo->bEraseOnReceive) -/
  1280.           {
  1281.           /* Mark message as read -/
  1282.           MessageHeader.wAttribute |= ATTRIB_RECEIVED;
  1283.           ++MessageHeader.wTimesRead;
  1284.  
  1285.           /* Attempt to rewrite message -/
  1286.           if(!WriteMessage(pInfo->szNetmailDir, lwCurrentMsgNum,
  1287.            &MessageHeader, pszText))
  1288.              {
  1289.              ToReturn = eGeneralFailure;
  1290.              }
  1291.           else
  1292.              {
  1293.              ToReturn = eSuccess;
  1294.              }
  1295.           }
  1296.  
  1297.            /* Deallocate message text buffer -/
  1298.            free(pszText);
  1299.  
  1300.            /* Return appropriate value -/
  1301.            return(ToReturn);
  1302.            }
  1303.         free(pszText);
  1304.         }
  1305.      } while(findnext(&DirEntry) == 0);
  1306.       }
  1307.  
  1308.    /* If no new messages were found -/
  1309.    return(eNoMoreMessages);
  1310.    }
  1311. */
  1312.  
  1313. tIBResult IBGetMail(tIBInfo *pInfo, ibbs_mail_type *ibmail)
  1314.    {
  1315.    tIBResult ToReturn;
  1316.    struct ffblk DirEntry;
  1317.    DWORD lwCurrentMsgNum;
  1318.    tMessageHeader MessageHeader;
  1319.    char szFileName[PATH_CHARS + FILENAME_CHARS + 2];
  1320.    char *pszText;//,key;
  1321.    tFidoNode ThisNode,OtherNode;
  1322.  
  1323. //   printf("1\n");
  1324.    /* Validate information structure */
  1325.    ToReturn = ValidateInfoStruct(pInfo);
  1326. //   printf("2\n");
  1327.    if(ToReturn != eSuccess) return(ToReturn);
  1328. //   printf("3\n");
  1329.  
  1330.    /* Get this node's address from string */
  1331.    ConvertStringToAddress(&ThisNode, pInfo->szThisNodeAddress);
  1332. //   printf("4\n");
  1333.  
  1334.    MakeFilename(pInfo->szNetmailDir, "*.msg", szFileName);
  1335. //   printf("5\n");
  1336.  
  1337.    /* Search through each message file in the netmail directory, in no */
  1338.    /* particular order.                                                */
  1339.    if(findfirst(szFileName, &DirEntry, FA_ARCH) == 0)
  1340.       {
  1341. //      printf("6\n");
  1342.       do
  1343.      {
  1344.      lwCurrentMsgNum = atol(DirEntry.ff_name);
  1345.  
  1346.      /* If able to read message */
  1347.      if(ReadMessage(pInfo->szNetmailDir, lwCurrentMsgNum, &MessageHeader,
  1348.         &pszText))
  1349.         {
  1350.         /* If message is for us, and hasn't be read yet */
  1351.         ConvertStringToAddress(&OtherNode,&MessageHeader.szToUserName[3]);
  1352. //        printf("7\n");
  1353.  
  1354.         if(stricmp(MessageHeader.szFromUserName, pInfo->szProgName) == 0
  1355.            && (ThisNode.wZone == OtherNode.wZone || OtherNode.wZone==0 || ThisNode.wZone==0)
  1356.            && ThisNode.wNet == OtherNode.wNet
  1357.            && ThisNode.wNode == OtherNode.wNode
  1358.            && ThisNode.wPoint == OtherNode.wPoint
  1359.            && !(MessageHeader.wAttribute & ATTRIB_RECEIVED))
  1360.            {
  1361.            /* Decode message text, placing information in buffer */
  1362. //           printf("8\n");
  1363.            DecodeMail(pszText, ibmail);
  1364. //           printf("*\n");
  1365. //           scanf("%c",&key);
  1366.  
  1367.            /* If received messages should be deleted */
  1368.            if(pInfo->bEraseOnReceive)
  1369.           {
  1370.           /* Determine filename of message to erase */
  1371.           GetMessageFilename(pInfo->szNetmailDir, lwCurrentMsgNum,
  1372.                      szFileName);
  1373.  
  1374.           /* Attempt to erase file */
  1375.           if(unlink(szFileName) == -1)
  1376.              {
  1377.              ToReturn = eGeneralFailure;
  1378.              }
  1379.           else
  1380.              {
  1381.              ToReturn = eSuccess;
  1382.              }
  1383.           }
  1384.  
  1385.            /* If received messages should not be deleted */
  1386.            else /* if(!pInfo->bEraseOnReceive) */
  1387.           {
  1388.           /* Mark message as read */
  1389.           MessageHeader.wAttribute |= ATTRIB_RECEIVED;
  1390.           ++MessageHeader.wTimesRead;
  1391.  
  1392.           /* Attempt to rewrite message */
  1393.           if(!WriteMessage(pInfo->szNetmailDir, lwCurrentMsgNum,
  1394.            &MessageHeader, pszText))
  1395.              {
  1396.              ToReturn = eGeneralFailure;
  1397.              }
  1398.           else
  1399.              {
  1400.              ToReturn = eSuccess;
  1401.              }
  1402.           }
  1403.  
  1404.            /* Deallocate message text buffer */
  1405.            free(pszText);
  1406.  
  1407.            /* Return appropriate value */
  1408.            return(ToReturn);
  1409.            }
  1410.         free(pszText);
  1411.         }
  1412.      } while(findnext(&DirEntry) == 0);
  1413.       }
  1414. //   printf("10\n");
  1415.    /* If no new messages were found */
  1416.    return(eNoMoreMessages);
  1417.  
  1418.    }
  1419.  
  1420.  
  1421. /*tIBResult IBGetR(tIBInfo *pInfo, void *pBuffer, int *nBufferLen)
  1422.    {
  1423.    tIBResult ToReturn;
  1424.    struct ffblk DirEntry;
  1425.    DWORD lwCurrentMsgNum;
  1426.    tMessageHeader MessageHeader;
  1427.    char szFileName[PATH_CHARS + FILENAME_CHARS + 2];
  1428.    char *pszText;
  1429.    tFidoNode ThisNode,OtherNode;
  1430.  
  1431.    /* Validate information structure -/
  1432.    ToReturn = ValidateInfoStruct(pInfo);
  1433.    if(ToReturn != eSuccess) return(ToReturn);
  1434.  
  1435.    /* Get this node's address from string -/
  1436.    ConvertStringToAddress(&ThisNode, pInfo->szThisNodeAddress);
  1437.  
  1438.    MakeFilename(pInfo->szNetmailDir, "*.msg", szFileName);
  1439.  
  1440.    /* Seach through each message file in the netmail directory, in no -/
  1441.    /* particular order.                                               -/
  1442.    if(findfirst(szFileName, &DirEntry, FA_ARCH) == 0)
  1443.       {
  1444.       do
  1445.      {
  1446.      lwCurrentMsgNum = atol(DirEntry.ff_name);
  1447.  
  1448.      /* If able to read message -/
  1449.      if(ReadMessage(pInfo->szNetmailDir, lwCurrentMsgNum, &MessageHeader,
  1450.         &pszText))
  1451.         {
  1452.         ConvertStringToAddress(&OtherNode,&MessageHeader.szToUserName[3]);
  1453.  
  1454.         if(strcmp(MessageHeader.szFromUserName, pInfo->szProgName) == 0
  1455.            && (ThisNode.wZone == OtherNode.wZone || OtherNode.wZone==0 || ThisNode.wZone==0)
  1456.            && ThisNode.wNet == OtherNode.wNet
  1457.            && ThisNode.wNode == OtherNode.wNode
  1458.            && ThisNode.wPoint == OtherNode.wPoint
  1459.            && !(MessageHeader.wAttribute & ATTRIB_RECEIVED))
  1460.            {
  1461.            /* Decode message text, placing information in buffer -/
  1462.            *nBufferLen=DecodeBufferR(pszText, pBuffer);
  1463.  
  1464.            /* If received messages should be deleted -/
  1465.            if(pInfo->bEraseOnReceive)
  1466.           {
  1467.           /* Determine filename of message to erase -/
  1468.           GetMessageFilename(pInfo->szNetmailDir, lwCurrentMsgNum,
  1469.                      szFileName);
  1470.  
  1471.           /* Attempt to erase file -/
  1472.           if(unlink(szFileName) == -1)
  1473.              {
  1474.              ToReturn = eGeneralFailure;
  1475.              }
  1476.           else
  1477.              {
  1478.              ToReturn = eSuccess;
  1479.              }
  1480.           }
  1481.  
  1482.            /* If received messages should not be deleted -/
  1483.            else /* if(!pInfo->bEraseOnReceive) -/
  1484.           {
  1485.           /* Mark message as read -/
  1486.           MessageHeader.wAttribute |= ATTRIB_RECEIVED;
  1487.           ++MessageHeader.wTimesRead;
  1488.  
  1489.           /* Attempt to rewrite message -/
  1490.           if(!WriteMessage(pInfo->szNetmailDir, lwCurrentMsgNum,
  1491.            &MessageHeader, pszText))
  1492.              {
  1493.              ToReturn = eGeneralFailure;
  1494.              }
  1495.           else
  1496.              {
  1497.              ToReturn = eSuccess;
  1498.              }
  1499.           }
  1500.  
  1501.            /* Deallocate message text buffer -/
  1502.            free(pszText);
  1503.  
  1504.            /* Return appropriate value -/
  1505.            return(ToReturn);
  1506.            }
  1507.         free(pszText);
  1508.         }
  1509.      } while(findnext(&DirEntry) == 0);
  1510.       }
  1511.  
  1512.    /* If no new messages were found -/
  1513.    return(eNoMoreMessages);
  1514.    }
  1515. */
  1516.  
  1517.  
  1518. void
  1519. ConvertAddressToString(char *pszDest, const tFidoNode *pNode)
  1520. {
  1521.   if(pNode->wZone == 0) {
  1522.     if(pNode->wPoint == 0) {
  1523.       sprintf(pszDest, "%u/%u", pNode->wNet, pNode->wNode);
  1524.     } else {
  1525.       sprintf(pszDest, "%u/%u.%u", pNode->wNet, pNode->wNode,pNode->wPoint);
  1526.     }
  1527.   } else {
  1528.     if(pNode->wPoint == 0) {
  1529.       sprintf(pszDest, "%u:%u/%u", pNode->wZone, pNode->wNet, pNode->wNode);
  1530.     } else {
  1531.       sprintf(pszDest, "%u:%u/%u.%u", pNode->wZone, pNode->wNet, pNode->wNode,pNode->wPoint);
  1532.     }
  1533.   }
  1534. }
  1535.  
  1536.  
  1537. void
  1538. ConvertStringToAddress(tFidoNode *pNode, const char *pszSource)
  1539. {
  1540.   pNode->wZone = 0;
  1541.   pNode->wNet = 0;
  1542.   pNode->wNode = 0;
  1543.   pNode->wPoint = 0;
  1544.   if(strchr(pszSource,':')==NULL) {
  1545.     sscanf(pszSource, "%u/%u.%u", &(pNode->wNet),&(pNode->wNode), &(pNode->wPoint));
  1546.   } else {
  1547.     sscanf(pszSource, "%u:%u/%u.%u", &(pNode->wZone), &(pNode->wNet),&(pNode->wNode), &(pNode->wPoint));
  1548.   }
  1549. }
  1550.  
  1551.  
  1552. #define NUM_KEYWORDS       14
  1553.  
  1554. #define KEYWORD_ADDRESS    0
  1555. #define KEYWORD_USER_NAME  1
  1556. #define KEYWORD_MAIL_DIR   2
  1557. #define KEYWORD_CRASH      3
  1558. #define KEYWORD_HOLD       4
  1559. #define KEYWORD_KILL_SENT  5
  1560. #define KEYWORD_KILL_RCVD  6
  1561. #define KEYWORD_LINK_WITH  7
  1562. #define KEYWORD_LINK_NAME  8
  1563. #define KEYWORD_LINK_LOC   9
  1564. #define KEYWORD_IBBS       10
  1565. #define KEYWORD_IBBS_OP    11
  1566. #define KEYWORD_IBBS_GN    12
  1567. #define KEYWORD_BBS_NAME   13
  1568.  
  1569.  
  1570. char *apszKeyWord[NUM_KEYWORDS] = {"SystemAddress",
  1571.                    "UserName",
  1572.                                    "NetmailDir",
  1573.                    "Crash",
  1574.                    "Hold",
  1575.                    "EraseOnSend",
  1576.                    "EraseOnReceive",
  1577.                    "LinkWith",
  1578.                    "LinkName",
  1579.                    "LinkLocation",
  1580.                    "InterBBS",
  1581.                    "InterBBSOperator",
  1582.                    "InterBBSGameNumber",
  1583.                    "SystemName"};
  1584.  
  1585. tIBResult IBReadConfig(tIBInfo *pInfo, char *pszConfigFile)
  1586.    {
  1587.    /* Set default values for pInfo settings */
  1588. /*   pInfo->nTotalSystems = 0;
  1589.    pInfo->paOtherSystem = NULL;*/
  1590.  
  1591.    /* Process configuration file */
  1592.    if(!ProcessConfigFile(pszConfigFile, NUM_KEYWORDS, apszKeyWord,
  1593.              ProcessConfigLine, (void *)pInfo))
  1594.       {
  1595.       return(eFileOpenError);
  1596.       }
  1597.  
  1598.    /* else */
  1599.    return(eSuccess);
  1600.    }
  1601.  
  1602.  
  1603. void ProcessConfigLine(int nKeyword, char *pszParameter, void *pCallbackData)
  1604.    {
  1605.    tIBInfo *pInfo = (tIBInfo *)pCallbackData;
  1606.    tOtherNode *paNewNodeArray;
  1607.  
  1608.    switch(nKeyword)
  1609.       {
  1610.       case KEYWORD_IBBS:
  1611.     ibbsi=TRUE;
  1612.     break;
  1613.  
  1614.       case KEYWORD_IBBS_OP:
  1615.     ibbsi_operator=TRUE;
  1616.     break;
  1617.  
  1618.       case KEYWORD_IBBS_GN:
  1619.     sscanf(pszParameter,"%d",&ibbsi_game_num);
  1620.     break;
  1621.  
  1622.       case KEYWORD_BBS_NAME:
  1623.     strncpy(bbs_namei,pszParameter,36);
  1624. //    printf("*|%s|",bbs_namei);
  1625.     break;
  1626.  
  1627.       case KEYWORD_ADDRESS:
  1628.      strncpy(pInfo->szThisNodeAddress, pszParameter, NODE_ADDRESS_CHARS);
  1629.      pInfo->szThisNodeAddress[NODE_ADDRESS_CHARS] = '\0';
  1630.      break;
  1631.  
  1632.       case KEYWORD_USER_NAME:
  1633.      strncpy(pInfo->szProgName, pszParameter, PROG_NAME_CHARS);
  1634.      pInfo->szProgName[PROG_NAME_CHARS] = '\0';
  1635.      break;
  1636.  
  1637.       case KEYWORD_MAIL_DIR:
  1638.      strncpy(pInfo->szNetmailDir, pszParameter, PATH_CHARS);
  1639.          pInfo->szNetmailDir[PATH_CHARS] = '\0';
  1640.      break;
  1641.  
  1642.       case KEYWORD_CRASH:
  1643.      if(stricmp(pszParameter, "Yes") == 0)
  1644.             {
  1645.             pInfo->bCrash = TRUE;
  1646.             }
  1647.      else if(stricmp(pszParameter, "No") == 0)
  1648.             {
  1649.         pInfo->bCrash = FALSE;
  1650.         }
  1651.          break;
  1652.  
  1653.       case KEYWORD_HOLD:
  1654.          if(stricmp(pszParameter, "Yes") == 0)
  1655.         {
  1656.             pInfo->bHold = TRUE;
  1657.             }
  1658.          else if(stricmp(pszParameter, "No") == 0)
  1659.         {
  1660.         pInfo->bHold = FALSE;
  1661.         }
  1662.      break;
  1663.  
  1664.       case KEYWORD_KILL_SENT:
  1665.      if(stricmp(pszParameter, "Yes") == 0)
  1666.             {
  1667.         pInfo->bEraseOnSend = TRUE;
  1668.             }
  1669.          else if(stricmp(pszParameter, "No") == 0)
  1670.         {
  1671.         pInfo->bEraseOnSend = FALSE;
  1672.         }
  1673.      break;
  1674.  
  1675.       case KEYWORD_KILL_RCVD:
  1676.      if(stricmp(pszParameter, "Yes") == 0)
  1677.         {
  1678.             pInfo->bEraseOnReceive = TRUE;
  1679.         }
  1680.      else if(stricmp(pszParameter, "No") == 0)
  1681.             {
  1682.         pInfo->bEraseOnReceive = FALSE;
  1683.         }
  1684.          break;
  1685.  
  1686.       case KEYWORD_LINK_WITH:
  1687.          if(pInfo->nTotalSystems == 0)
  1688.         {
  1689.         pInfo->paOtherSystem = (tOtherNode *)malloc(sizeof(tOtherNode));
  1690.         if(pInfo->paOtherSystem == NULL)
  1691.            {
  1692.            break;
  1693.                }
  1694.             }
  1695.      else
  1696.             {
  1697.         if((paNewNodeArray = (tOtherNode *)malloc(sizeof(tOtherNode) *
  1698.          (pInfo->nTotalSystems + 1))) == NULL)
  1699.                {
  1700.            break;
  1701.            }
  1702.  
  1703.         memcpy(paNewNodeArray, pInfo->paOtherSystem, sizeof(tOtherNode) *
  1704.                pInfo->nTotalSystems);
  1705.  
  1706.             free(pInfo->paOtherSystem);
  1707.  
  1708.             pInfo->paOtherSystem = paNewNodeArray;
  1709.         }
  1710.  
  1711.          strncpy(pInfo->paOtherSystem[pInfo->nTotalSystems].szAddress,
  1712.          pszParameter, NODE_ADDRESS_CHARS);
  1713.      pInfo->paOtherSystem[pInfo->nTotalSystems].
  1714.             szAddress[NODE_ADDRESS_CHARS] = '\0';
  1715.      ++pInfo->nTotalSystems;
  1716.          break;
  1717.  
  1718.       case KEYWORD_LINK_NAME:
  1719.      if(pInfo->nTotalSystems != 0)
  1720.         {
  1721.         strncpy(pInfo->paOtherSystem[pInfo->nTotalSystems - 1].szSystemName,
  1722.             pszParameter, SYSTEM_NAME_CHARS);
  1723.             pInfo->paOtherSystem[pInfo->nTotalSystems - 1].
  1724.            szSystemName[SYSTEM_NAME_CHARS] = '\0';
  1725.         }
  1726.          break;
  1727.  
  1728.       case KEYWORD_LINK_LOC:
  1729.          if(pInfo->nTotalSystems != 0)
  1730.         {
  1731.         strncpy(pInfo->paOtherSystem[pInfo->nTotalSystems - 1].szLocation,
  1732.             pszParameter, LOCATION_CHARS);
  1733.         pInfo->paOtherSystem[pInfo->nTotalSystems - 1].
  1734.            szLocation[LOCATION_CHARS] = '\0';
  1735.             }
  1736.      break;
  1737.       }
  1738.    }
  1739.  
  1740.  
  1741. /* Configuration file reader settings */
  1742. #define CONFIG_LINE_SIZE 128
  1743. #define MAX_TOKEN_CHARS 32
  1744.  
  1745. tBool ProcessConfigFile(char *pszFileName, int nKeyWords, char **papszKeyWord,
  1746.           void (*pfCallBack)(int, char *, void *), void *pCallBackData)
  1747.    {
  1748.    FILE *pfConfigFile;
  1749.    char szConfigLine[CONFIG_LINE_SIZE + 1];
  1750.    char *pcCurrentPos;
  1751.    unsigned int uCount;
  1752.    char szToken[MAX_TOKEN_CHARS + 1];
  1753.    int iKeyWord;
  1754.  
  1755.    /* Attempt to open configuration file */
  1756.    if((pfConfigFile = fopen(pszFileName, "rt")) == NULL)
  1757.       {
  1758.       return(FALSE);
  1759.       }
  1760.  
  1761.    /* While not at end of file */
  1762.    while(!feof(pfConfigFile))
  1763.       {
  1764.       /* Get the next line */
  1765.       if(fgets(szConfigLine, CONFIG_LINE_SIZE + 1 ,pfConfigFile) == NULL) break;
  1766.  
  1767.       /* Ignore all of line after comments or CR/LF char */
  1768.       pcCurrentPos=(char *)szConfigLine;
  1769.       while(*pcCurrentPos)
  1770.      {
  1771.          if(*pcCurrentPos=='\n' || *pcCurrentPos=='\r' || *pcCurrentPos==';')
  1772.         {
  1773.         *pcCurrentPos='\0';
  1774.             break;
  1775.         }
  1776.          ++pcCurrentPos;
  1777.          }
  1778.  
  1779.       /* Search for beginning of first token on line */
  1780.       pcCurrentPos=(char *)szConfigLine;
  1781.       while(*pcCurrentPos && isspace(*pcCurrentPos)) ++pcCurrentPos;
  1782.  
  1783.       /* If no token was found, proceed to process the next line */
  1784.       if(!*pcCurrentPos) continue;
  1785.  
  1786.       /* Get first token from line */
  1787.       uCount=0;
  1788.       while(*pcCurrentPos && !isspace(*pcCurrentPos))
  1789.      {
  1790.      if(uCount<MAX_TOKEN_CHARS) szToken[uCount++]=*pcCurrentPos;
  1791.      ++pcCurrentPos;
  1792.      }
  1793.       if(uCount<=MAX_TOKEN_CHARS)
  1794.      szToken[uCount]='\0';
  1795.       else
  1796.      szToken[MAX_TOKEN_CHARS]='\0';
  1797.  
  1798.       /* Find beginning of configuration option parameters */
  1799.       while(*pcCurrentPos && isspace(*pcCurrentPos)) ++pcCurrentPos;
  1800.  
  1801.        /* Trim trailing spaces from setting string */
  1802.       for(uCount=strlen(pcCurrentPos)-1;uCount>0;--uCount)
  1803.      {
  1804.          if(isspace(pcCurrentPos[uCount]))
  1805.         {
  1806.         pcCurrentPos[uCount]='\0';
  1807.             }
  1808.      else
  1809.         {
  1810.         break;
  1811.         }
  1812.      }
  1813.  
  1814.       /* Loop through list of keywords */
  1815.       for(iKeyWord = 0; iKeyWord < nKeyWords; ++iKeyWord)
  1816.      {
  1817. //     printf("|%s|",papszKeyWord[iKeyWord]);
  1818. //     printf("|>%d=%d<|\n",iKeyWord,KEYWORD_BBS_NAME);
  1819.  
  1820.      /* If keyword matches */
  1821.      if(stricmp(szToken, papszKeyWord[iKeyWord]) == 0)
  1822.         {
  1823. //        printf("|%s|",szToken);
  1824. //        printf("|>%d=%d<|",iKeyWord,KEYWORD_BBS_NAME);
  1825.         /* Call keyword processing callback function */
  1826.         (*pfCallBack)(iKeyWord, pcCurrentPos, pCallBackData);
  1827.         }
  1828.      }
  1829.       }
  1830.  
  1831.    /* Close the configuration file */
  1832.    fclose(pfConfigFile);
  1833.  
  1834.    /* Return with success */
  1835.    return(TRUE);
  1836.    }
  1837.